package com.jdbc.demo01.dao;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

/**
 * @author ZebinHong
 * @create 2021-07-25-18:14
 */
public abstract class BaseDao<T> {
    private QueryRunner qr = new QueryRunner();
    private Class<T> type;
    public BaseDao(){
        // 获取子类的类型
        Class clazz = this.getClass();
        // 获取父类的类型
        // getGenericSuperclass()用来获取当前类的父类的类型
        // ParameterizedType表示的是带泛型的类型
        ParameterizedType parameterizedType = (ParameterizedType) clazz.getGenericSuperclass();
        // 获取具体的泛型类型 getActualTypeArguments获取具体的泛型的类型
        // 这个方法会返回一个Type的数组
        Type[] types = parameterizedType.getActualTypeArguments();
        // 获取具体的泛型的类型·
        this.type = (Class<T>) types[0];
    }
    /**
     * 增删改操作
     * @param con
     * @param sql
     * @param args
     * @return
     */
    public int update(Connection con, String sql, Object ...args){
        int update = 0;
        try {
            update = qr.update(con, sql, args);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return update;
    }

    /**
     * 获取一个对象
     * @param con
     * @param sql
     * @param args
     * @return
     */
    public T getBean(Connection con,String sql,Object ...args) {
        T query = null;
        try {
            query = qr.query(con, sql, new BeanHandler<T>(type), args);
            return query;
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return null;
    }

    /**
     * 获取多个对象
     * @param con
     * @param sql
     * @param args
     * @return
     */
    public List<T> getBeanList(Connection con,String sql,Object ...args){
        List<T> querys = null;
        try {
            querys = qr.query(con, sql, new BeanListHandler<T>(type), args);
            return querys;
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return null;
    }
    /**
     * 获取一个但一值得方法，专门用来执行像 select count(*)...这样的sql语句
     *
     * @param sql
     * @param args
     * @return
     */
    public Object getValue(Connection con,String sql,Object ...args){
        Object query = null;
        try {
            query = qr.query(con, sql, new ScalarHandler(), args);
            return query;
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return null;
    }
}
